 // vue2对象响应式原理： Object.definedProperty()   对属性进行拦截
 // vue2数组响应式原理：
 // 从数组圆形中获取这7个方法 并覆盖为可以发送更新通知的函数实现
 const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort']
 const originalProto = Array.prototype
 const arrayProto = Object.create(originalProto)
 methods.forEach(method => {
     arrayProto[method] = function() {
         originalProto[method].apply(this, arguments)
             // 通知更新
         notifyUpdate()
     }
 });


 // observe思想 递归遍历传入的obj  定义每个属性的拦截
 // observe  
 function observe(obj) {
     if (typeof obj !== 'object' || obj === null) {
         return obj
     }
     if (Array.isArray(obj)) {
         Object.setPrototypeOf(obj, arrayProto)
     } else {

         const keys = Object.keys(obj)
         for (let index = 0; index < keys.length; index++) {
             const key = keys[index];
             // 取出每个key 对obj每个key执行拦截
             defineReactive(obj, key, obj[key])
         }
     }
 }
 // 具体的定义指定的key拦截器
 function defineReactive(obj, key, val) {
     observe(val)
     Object.defineProperty(obj, key, {
         get() {
             return val
         },
         set(newVal) {
             if (newVal !== val) {
                 // nweVal可能是对象
                 observe(newVal)
                 notifyUpdate()
                 val = newVal
             }
         }
     })
 }

 function notifyUpdate() {
     console.log("页面更新")
 }

 const data = {
     foo: 'foo',
     b: {
         a: 1
     },
     list: [1, 2, 3]
 }

 observe(data)
     // 普通更新
     //  data.foo="foooooooo"
     // 嵌套更新
     // data.b.a=10
     // 对象更新
     // data.b={a:100}
     // data.list.push(4)
     // console.log(data)



 //  问题分析
 // 1. 需要响应化的数据较大时，递归遍历性能不好 消耗较大   
 // 2. 新增或删除属性无法监听
 // 3. 数组相应化需要额外实现
 // 4. 修改语法有限制